﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ModelQuality.Metrics.Model;
using ModelQuality.Metrics.Engine;

namespace ModelQuality.Metrics.Rules
{
    partial class DiagramRule : IValidationRule<DiagramVO>
    {
        public bool Matches(DiagramVO diagram)
        {
            bool matches;
            if (selector == null)
            {
                matches = true;
            }
            else
            {
                bool typeOK = selector.type == DiagramType.UNKNOWN || selector.type == diagram.DiagramType;
                bool locationOK = String.IsNullOrEmpty(selector.location)
                                    || context.RepositoryServices.IsDiagramInPackage(diagram, context.RepositoryServices.GetPackage(selector.location));

                matches = typeOK && locationOK;
            }

            return matches;
        }

        public ValidationResult Validate(DiagramVO diagram)
        {
            bool ok;

            var objs = Projections.From(diagramVerification.checkType)
                                    .Apply(diagram, context);

            var pred = Predicates.From(diagramVerification.operation);
            var parameters = Parameter.From(diagramVerification.parameters);
            if (pred.CanApply(objs, parameters, context))
            {
                ok = pred.Apply(objs, parameters, context);
            }
            else
            {
                throw new EngineException("Predicate matching error");
            }

            return new ValidationResult(diagram, ok ? ValidationStatus.OK : ValidationStatus.KO);
        }

        public override IList<ValidationRule> GetSubRules()
        {
            return diagramRule != null ? new List<ValidationRule>(diagramRule) : new List<ValidationRule>();
        }

        public override string ToString()
        {
            return String.Format("DiagramRule[{0}]", id);
        }
    }
}
